package org.jz.gae.redbook.spb.server.controller;

import java.util.List;

import org.jz.gae.redbook.spb.server.cache.DistrictCashe;
import org.jz.gae.redbook.spb.server.cache.FamilyCashe;
import org.jz.gae.redbook.spb.server.cache.LocationCashe;
import org.jz.gae.redbook.spb.server.cache.SpeciesCashe;
import org.jz.gae.redbook.spb.server.helper.LocationHelper;
import org.jz.gae.redbook.spb.server.helper.RedBookHelper;
import org.jz.gae.redbook.spb.shared.LocationEntityView;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

public class LocationControllerGoogle implements LocationController
{

	@Override
	public void loadLocationList(
			List<LocationEntityView> _LocationList)
	{
	    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	    Key redbookKey = KeyFactory.createKey(RedBookHelper.RED_BOOK_SIGN, RedBookHelper.RED_BOOK_NAME);
	    Query query = new Query(LocationHelper.ENTITY_NAME, redbookKey).addSort(LocationHelper.LOCATION_WORK_NAME, Query.SortDirection.ASCENDING);
	    List<Entity> locations = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
	    if (locations.isEmpty()) 
	    {
	    	_LocationList.clear();
	    } 
	    else 
	    {
	    	_LocationList.clear();
    		DistrictCashe districtCashe = DistrictCasheGoogle.getInstance();
    		SpeciesCashe speciesCashe = SpeciesCasheGoogle.getInstance();
	    	for (Entity location : locations)
	    	{
	    		LocationEntityView newLocation = new LocationEntityView();
	    		LocationUtils.reflectEntityToView(location, newLocation);
	    		newLocation.setLocationDistrictPresentation(districtCashe.getEntityView(newLocation.getLocationDistrictKey()).getDistrictRusName());
	    		if ((newLocation.getLocationSpeciesKey() != null) && (!"".equals(newLocation.getLocationSpeciesKey())))
	    		{
	    		    newLocation.setLocationSpeciesPresentation(speciesCashe.getEntityView(newLocation.getLocationSpeciesKey()).getSpeciesLatName());
	    		}
	    		/**/
	    		_LocationList.add(newLocation);
	    	}
	    }		
	}

	@Override
	public void loadLocationListForSpecies(
			String _SpeciesKey,
			List<LocationEntityView> _LocationList)
	{
		Key speciesKey = KeyFactory.stringToKey(_SpeciesKey);
		/**/
	    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	    Key redbookKey = KeyFactory.createKey(RedBookHelper.RED_BOOK_SIGN, RedBookHelper.RED_BOOK_NAME);
	    Query query = new Query(LocationHelper.ENTITY_NAME, redbookKey).
	    		addFilter(LocationHelper.LOCATION_SPECIES_KEY, FilterOperator.EQUAL, speciesKey).
	    		addSort(LocationHelper.LOCATION_WORK_NAME, Query.SortDirection.ASCENDING);
	    List<Entity> locations = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
	    if (locations.isEmpty()) 
	    {
	    	_LocationList.clear();
	    } 
	    else 
	    {
	    	_LocationList.clear();
    		DistrictCashe districtCashe = DistrictCasheGoogle.getInstance();
    		SpeciesCashe speciesCashe = SpeciesCasheGoogle.getInstance();
	    	for (Entity location : locations)
	    	{
	    		LocationEntityView newLocation = new LocationEntityView();
	    		LocationUtils.reflectEntityToView(location, newLocation);
	    		newLocation.setLocationDistrictPresentation(districtCashe.getEntityView(newLocation.getLocationDistrictKey()).getDistrictRusName());
	    		if ((newLocation.getLocationSpeciesKey() != null) && (!"".equals(newLocation.getLocationSpeciesKey())))
	    		{
	    		    newLocation.setLocationSpeciesPresentation(speciesCashe.getEntityView(newLocation.getLocationSpeciesKey()).getSpeciesLatName());
	    		}
	    		/**/
	    		_LocationList.add(newLocation);
	    	}
	    }		
	}

	@Override
	public LocationEntityView loadLocation(
			String _LocationKey) throws Exception
	{
		System.err.println("extraction key : " + _LocationKey);
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Entity location = datastore.get(KeyFactory.stringToKey(_LocationKey));
		System.err.println("extracted");
		LocationEntityView result = new LocationEntityView();
		LocationUtils.reflectEntityToView(location, result);
		DistrictCashe districtCashe = DistrictCasheGoogle.getInstance();
		result.setLocationDistrictPresentation(districtCashe.getEntityView(result.getLocationDistrictKey()).getDistrictRusName());
		if ((result.getLocationSpeciesKey() != null) && (!"".equals(result.getLocationSpeciesKey())))
		{
		    SpeciesCashe speciesCashe = SpeciesCasheGoogle.getInstance();
		    result.setLocationSpeciesPresentation(speciesCashe.getEntityView(result.getLocationSpeciesKey()).getSpeciesLatName());
		}
        return result;
	}

	@Override
	public void updateLocation(
			LocationEntityView _LocationToEdit) throws Exception
	{
		System.err.println("extraction key : " + _LocationToEdit.getLocationKey());
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Entity location = datastore.get(KeyFactory.stringToKey(_LocationToEdit.getLocationKey()));
		System.err.println("extracted");
		LocationUtils.reflectViewToEntity(_LocationToEdit, location);
        datastore.put(location);
		System.err.println("updated");
	}

	@Override
	public void deleteLocation(
			LocationEntityView _LocationToDelete)
	{
		System.err.println("deletion key : " + _LocationToDelete.getLocationKey());
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        datastore.delete(KeyFactory.stringToKey(_LocationToDelete.getLocationKey()));
		System.err.println("deleted");
	}

	@Override
	public void createLocation(
			LocationEntityView _LocationToAppend)
	{
	    Key redbookKey = KeyFactory.createKey(RedBookHelper.RED_BOOK_SIGN, RedBookHelper.RED_BOOK_NAME);
		Entity newLocation = new Entity(LocationHelper.ENTITY_NAME, redbookKey);
		LocationUtils.reflectViewToEntity(_LocationToAppend, newLocation);
        /**/
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        datastore.put(newLocation);
		System.err.println("new key : " + newLocation.getKey());
		_LocationToAppend.setLocationKey(KeyFactory.keyToString(newLocation.getKey()));
	}

}
